package com.derby.nuke.gradle.dependencymanagement;

import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.logging.Logger;
import org.gradle.api.plugins.*;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.tasks.bundling.War;

import java.io.File;
import java.util.Arrays;

public class DependencyManagementPlugin implements Plugin<Project> {
    public static final String Task_Group_Nuke = "Nuke";
    public static final String PROP_PROJECT_NAME = "@ProjectName";

    @Override
    public void apply(Project project) {
        project.getLogger().info("This is test: @129");
        project.getPluginManager().apply(JavaBasePlugin.class);
        BasePluginConvention convention = project.getConvention().getPlugin(BasePluginConvention.class);

        //TODO: config archeive name
        ExtraPropertiesExtension extraProperties = project.getExtensions().getExtraProperties();
        extraProperties.set(PROP_PROJECT_NAME, project.getName().replaceAll("-", ""));

        new PackageConfiguration(project).configure(convention);

        createJavaDirTask(project);
        createWebProject(project);

        print(project, convention);
    }


    private void createJavaDirTask(Project project) {
        Task createJavaDir = project.getTasks().create("createJavaDir");
        createJavaDir.setGroup(Task_Group_Nuke);
        createJavaDir.getActions().add(task -> {
            JavaPluginConvention javaConvention = project.getConvention().getPlugin(JavaPluginConvention.class);
            SourceSetContainer sourceSets = javaConvention.getSourceSets();

            sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getJava().getSrcDirs().forEach(this::createIfNotExist);
            sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getResources().getSrcDirs().forEach(this::createIfNotExist);
            sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME).getJava().getSrcDirs().forEach(this::createIfNotExist);
            sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME).getResources().getSrcDirs().forEach(this::createIfNotExist);

        });

    }

    private void createWebProject(Project project) {
        Task createWebDir = project.getTasks().create("createWebDir");
        createWebDir.dependsOn(":createJavaDir");
        createWebDir.setGroup(Task_Group_Nuke);
        createWebDir.getActions().add(task -> {
            WarPluginConvention warPluginConvention = project.getConvention().getPlugin(WarPluginConvention.class);

            File file = new File(project.getRootDir(), warPluginConvention.getWebAppDirName());
            createIfNotExist(file);
        });

    }

    private boolean createIfNotExist(File file) {
        return file.exists() || file.mkdirs();
    }


    private void print(Project project, BasePluginConvention convention) {
        Jar jarTask = (Jar) project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME);
        War warTask = (War) project.getTasks().getByName(WarPlugin.WAR_TASK_NAME);
        String formatProjectName = project.getExtensions().getExtraProperties().get(PROP_PROJECT_NAME).toString();
        Task print = project.getTasks().create("print");
        print.setGroup(Task_Group_Nuke);
        Logger logger = project.getLogger();

        print.setActions(Arrays.asList((Action<Task>) task -> {

            logger.info("Version:{}", project.getVersion());
            logger.info("Group:{}", project.getGroup());
            logger.info("ProjectName:{}", project.getName());
            logger.info("Desc: {}", project.getDescription());
            logger.info("BuildDir: {}", project.getBuildDir().toString());
            logger.info("ProjectDir: {}", project.getProjectDir().toString());
            logger.info("GetRootDir: {}", project.getRootDir().toString());
            logger.info("RootProject.GetRootDir: {}", project.getRootProject().getRootDir().toString());
            logger.info("ArchivesBaseName: {}", convention.getArchivesBaseName());
            logger.info("Formated.projectName", formatProjectName);


            project.getExtensions().getExtraProperties().getProperties().forEach((k, v) -> {
                logger.info("ExtraProps: {} - {}", k, v);
            });

            project.getComponents().getNames().forEach(name -> {
                logger.info("Components.name: {}", name);
            });

            project.getConfigurations().getNames().forEach(name -> {
                logger.info("Configuration.name: {}", name);
            });


            jarTask.getOutputs().getFiles().forEach(file -> {
                logger.info("jarTask:{}", file.getName());
            });


            warTask.getClasspath().getFiles().forEach(file -> {
                logger.info("warTask:{}", file.getName());

            });



        }));


    }


}
